#include "gamecontrol.h"

GameControl::GameControl(int w, int h, int r)
{
    isPlaying = false;
    isPlayer = true;
    celW = w;   //设置每一格的宽
    celH = h;  //设置每一格的高
    row = r; //设置行列数
    msg = new Message();
    gameData = new char[row*row]; //生成游戏数据数组
    playerData = new int[row*row]; //生成玩家棋盘分析表
    computerData = new int[row*row];  //生成电脑棋盘分析表
    initData();

}

GameControl::~GameControl()
{
    delete gameData;
    delete playerData;
    delete computerData;
}

//初始化游戏数据
void GameControl::initData()
{
    for (int i = 0; i < row*row; i++)
    {
        gameData[i] = '0';

        playerData[i] = 0;
        computerData[i] = 0;
    }
}

//填充游戏数据
void GameControl::setData(QPoint p)
{
    char data;

    if (isPlayer)
    {
        data = 'p';
    }
    else
    {
        data = 'c';
    }

    gameData[p.y()*row + p.x()] = data;

    setPlayerData();
    setComputerData();

    if (isNoPlace())
    {
        msg->noPlace();
        isPlaying = false;
    }

}

//填充玩家棋盘分析表
void GameControl::setPlayerData()
{
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < row; j++)
        {
            if (gameData[i*row+j] == '0')
            {
                //向前遍历
                int count = 0;
                int score = 0;
                for (int k = j+1; gameData[i*row+k] == 'p' && k < row; k++)
                {
                    count++;
                }
                score += countScore(count);
                //向后遍历
                count = 0;
                for (int k = j-1; gameData[i*row+k] == 'p' && k > 0; k--)
                {
                    count++;
                }
                score += countScore(count);

                //向左下角遍历
                count = 0;
                for (int k = j-1, l = i+1; gameData[l*row+k] == 'p' && k >= 0 && l < row; k--, l++)
                {
                    count++;
                }
                score += countScore(count);
                //向右上角遍历
                count = 0;
                for (int k = j+1, l = i-1; gameData[l*row+k] == 'p' && l >= 0 && k < row; l--, k++)
                {
                    count++;
                }
                score += countScore(count);
                //向右下角遍历
                count = 0;
                for (int k = j+1, l = i+1; gameData[l*row+k] == 'p' && k < row && l < row; l++, k++)
                {
                    count++;
                }
                score += countScore(count);
                //向左上角遍历
                count = 0;
                for (int k = j-1, l = i-1; gameData[l*row+k] == 'p' && k > 0 && l > 0; l--, k--)
                {
                    count++;
                }
                score += countScore(count);
                //向正下方遍历
                count = 0;
                for (int k = i+1; gameData[k*row+j] == 'p' && k < row; k++)
                {
                    count++;
                }
                score += countScore(count);
                //向正上方遍历
                count = 0;
                for (int k = i-1; gameData[k*row+j] == 'p' && k > 0; k--)
                {
                    count++;
                }
                score += countScore(count);

                playerData[i*row+j] = score;
            }
        }
    }
}

//填充电脑棋盘分析表
void GameControl::setComputerData()
{
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < row; j++)
        {
            if (gameData[i*row+j] == '0')
            {
                //向前遍历
                int count = 0;
                int score = 0;
                for (int k = j+1; gameData[i*row+k] == 'c' && k < row; k++)
                {
                    count++;
                }
                score += countScore(count);
                //向后遍历
                count = 0;
                for (int k = j-1; gameData[i*row+k] == 'c' && k > 0; k--)
                {
                    count++;
                }
                score += countScore(count);

                //向左下角遍历
                count = 0;
                for (int k = j-1, l = i+1; gameData[l*row+k] == 'c' && k >= 0 && l < row; k--, l++)
                {
                    count++;
                }
                score += countScore(count);
                //向右上角遍历
                count = 0;
                for (int k = j+1, l = i-1; gameData[l*row+k] == 'c' && l >= 0 && k < row; l--, k++)
                {
                    count++;
                }
                score += countScore(count);
                //向右下角遍历
                count = 0;
                for (int k = j+1, l = i+1; gameData[l*row+k] == 'c' && k < row && l < row; l++, k++)
                {
                    count++;
                }
                score += countScore(count);
                //向左上角遍历
                count = 0;
                for (int k = j-1, l = i-1; gameData[l*row+k] == 'c' && k > 0 && l > 0; l--, k--)
                {
                    count++;
                }
                score += countScore(count);
                //向正下方遍历
                count = 0;
                for (int k = i+1; gameData[k*row+j] == 'c' && k < row; k++)
                {
                    count++;
                }
                score += countScore(count);
                //向正上方遍历
                count = 0;
                for (int k = i-1; gameData[k*row+j] == 'c' && k > 0; k--)
                {
                    count++;
                }
                score += countScore(count);


                computerData[i*row+j] = score;
            }
        }
    }
}

//计算每个空位的分数
int GameControl::countScore(int count)
{
    int score = 0;
    switch (count)
    {
    case 1:
        score = 1;
        break;
    case 2:
        score = 5;
        break;
    case 3:
        score = 25;
        break;
    case 4:
        score = 125;
        break;
    default:
        break;
    }
    return score;
}

//设置游戏是否进行中
void GameControl::setPlaying(bool b)
{
    isPlaying = b;
}

//设置是否到玩家落子
void GameControl::setPlayer(bool b)
{
    isPlayer = b;
}

//设置单元格的宽
void GameControl::setCelW(int w)
{
    celW = w;
}

//设置单元格的高
void GameControl::setCelH(int h)
{
    celH = h;
}

//设置行列数
void GameControl::setRow(int r)
{
    row = r;
}

//获取游戏是否进行中
bool GameControl::getIsPlaying()
{
    return isPlaying;
}

//获取是否到玩家落子
bool GameControl::getIsPlayer()
{
    return isPlayer;
}

//转换界面坐标成数组下标
QPoint GameControl::translate(QPoint p)
{
    QPoint newP;

    newP.setX( (p.x()+celW/2) / celW - 1);
    newP.setY( (p.y()+celH/2) / celH - 1);

    return newP;
}

//检查是否赢了
bool GameControl::checkWin()
{
    int count = 0;

    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < row; j++)
        {
            if (gameData[i*row+j] == data)
            {
                //向前遍历
                count = 1;
                for (int k = j+1; gameData[i*row+k] == data && k < row; k++)
                {
                    count++;
                }

                if (count >= 5)
                {
                    return true;
                }
                //向左下角遍历
                count = 1;
                for (int k = j-1, l = i+1; gameData[l*row+k] == data && k >= 0 && l < row; k--, l++)
                {
                    count++;
                }

                if (count >= 5)
                {
                    return true;
                }
                //向右下角遍历
                count = 1;
                for (int k = j+1, l = i+1; gameData[l*row+k] == data && k < row && l < row; l++, k++)
                {
                    count++;
                }

                if (count >= 5)
                {
                    return true;
                }
                //向正下方遍历
                count = 1;
                for (int k = i+1; gameData[k*row+j] == data && k < row; k++)
                {
                    count++;
                }

                if (count >= 5)
                {
                    return true;
                }
            }
        }
    }

    return false;
}

//检查是否是玩家赢了
bool GameControl::isPlayerWin()
{
    data = 'p';

    if (checkWin())
    {
        msg->playerWin();
        setPlaying(false);

        return true;
    }
    return false;
}

//检查是否是电脑赢了
bool GameControl::isComputerWin()
{
    data = 'c';

    if (checkWin())
    {
        msg->computerWin();
        setPlaying(false);

        return true;
    }
    return false;
}

//检查是否没位置落子了
bool GameControl::isNoPlace()
{
    for (int i = 0; i < row*row; i++)
    {
        if (gameData[i] == '0')
        {
            return false;
        }
    }
    return true;
}

//检查位置是否已有棋子
bool GameControl::isHaveChess(QPoint p)
{
    QPoint newP;

    if (isPlayer)
    {
        newP = translate(p);
    }
    else
    {
        newP = p;
    }

    if (gameData[newP.y()*row+newP.x()] == '0')
    {
        setData(newP);
        return false;
    }


    return true;
}

//电脑落子位置计算
QPoint GameControl::computerMove()
{
    QPoint p;

    int max = 0, sum;

    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < row; j++)
        {
            sum = 0;
            if (gameData[i*row+j] == '0')
            {
                sum += (computerData[i*row+j] + playerData[i*row+j]);

                if (sum > max)
                {
                    p.setX(j);
                    p.setY(i);
                    max = sum;
                }
                if (max == 0)
                {
                    p.setX(7);
                    p.setY(7);
                }
            }
        }
    }

    if (!isPlayer)
    {
        int i = p.x(), j = p.y();
        if (!isHaveChess(QPoint(i, j)))
        {
            p.setX((i+1)*celW - celW/2);
            p.setY((j+1)*celH - celH/2);

            return p;
        }

    }
}
